home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / COMMUNIC / 2500.ZIP / WKERMIT.ZIP / WINKPR.C < prev    next >
C/C++ Source or Header  |  1990-11-19  |  33KB  |  1,319 lines

  1.  
  2. /* WARNING -- This C source program generated by Wart preprocessor. */
  3. /* Do not edit this file; edit the Wart-format source file instead, */
  4. /* and then run it through Wart to produce a new C source file.     */
  5.  
  6. /* Wart Version Info: */
  7. char *wartv = "Wart Version 1A(005) Jan 1988";
  8.  
  9. /*
  10.  * Windows Kermit
  11.  * 
  12.  * Written by William S. Hall
  13.  *          3665 Benton Street, #66
  14.  *          Santa Clara, CA 95051
  15.  *
  16.  * protocol module
  17.  */
  18.  
  19. #define NOKANJI
  20. #define NOATOM
  21. #define NOMINMAX
  22. #include <windows.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <io.h>
  26. #include <stdio.h>
  27. #include <limits.h>
  28. #include <sys\types.h>
  29. #include <sys\stat.h>
  30.  
  31. #define EXTERN
  32.  
  33. #include "winasc.h"
  34. #include "winkpr.h"
  35. #include "winkpf.h"
  36.  
  37. extern cid;
  38.  
  39. /* local functions */
  40. static BOOL NEAR paritycheck(void);
  41. static int NEAR wart(void);
  42. static void NEAR ShowTransactionError(HWND, int);
  43. static void NEAR scmd(char cmd);
  44. static void NEAR ttoi(BYTE *buf, int len);
  45. static int NEAR input(void);
  46. static void NEAR errpkt(HWND hWnd, int id);
  47. static int NEAR opent(HWND);
  48. static int NEAR sinit(void);
  49. static void NEAR sipkt(char c);
  50. static int NEAR sfile(void);
  51. static void NEAR seof(char *s);
  52. static int NEAR sdata(void);
  53. static void NEAR ack(int len, BYTE *s);
  54. static int NEAR nxtpkt(void);
  55. static int NEAR canned(char *buf);
  56. static int NEAR gnfile(void);
  57. static void NEAR seot(void);
  58. static void NEAR rinit(void);
  59. static void NEAR resetc(void);
  60. static void NEAR resend(void);
  61. static int NEAR rcvfil(void);
  62. static void NEAR reot(void);
  63. static int NEAR reof(void);
  64. static void NEAR srinit(void);
  65. static void NEAR spar(BYTE *data, int len);
  66. static int NEAR rpar(BYTE *data);
  67. static void NEAR spack(BYTE type, int num, int len, BYTE *data);
  68. static int NEAR bufill(BYTE buffer[]);
  69. static int NEAR encodebuf(BYTE outbuf[], BYTE inbuf[], int *inbufsize);
  70. static int NEAR bufemp(BYTE *buffer, int len, int dest);
  71. static HANDLE NEAR GetSendFileName(char *name);
  72. static HANDLE NEAR GetReceiveFileName(HWND hWnd, BYTE *packet);
  73. static void NEAR ShowErrorPacket(HWND hWnd, char *errstr);
  74. static int NEAR getpacket(BYTE *str, int len);
  75. static int NEAR input(void);
  76. static void NEAR UpdateXferBox(void);
  77.  
  78. /* timer function */
  79. void FAR PASCAL krmDoTimeout(HWND hWnd,unsigned message,short event,DWORD time)
  80. {
  81.  
  82.     KillTimer(hWnd, event);
  83.     if (Kermit.bell)
  84.         MessageBeep(0);
  85.  
  86.     rcvpkt.state = PS_SYNCH;
  87.     Kermit.inpacket = FALSE;
  88.     switch(event) {
  89.     case KRM_WAITSEND:
  90.         Kermit.waitsend = FALSE;
  91.         break;
  92.     default:
  93.         Kermit.timeout = TRUE;
  94.         break;
  95.     }
  96. }
  97.  
  98. /* local variables */
  99. static int lclcount;
  100. static BYTE *lclbuf;
  101. static HWND lclhWnd;
  102.  
  103. /* dispatch a string from the comm port.  return when used up */
  104. void krmKermitDispatch(HWND hWnd, BYTE *buf, int count)
  105. {
  106.  
  107.  
  108.     if (Kermit.waitsend)
  109.     return;
  110.  
  111.     lclcount = count;
  112.     lclbuf = buf;
  113.     lclhWnd = hWnd;
  114.  
  115.     wart();
  116.  
  117.     if (Kermit.sstate < 0)
  118.     SendMessage(lclhWnd, WM_COMMAND, IDM_CANCELPROTOCOL, (LONG)krmState);
  119. }
  120.  
  121. /* protocol stuff */
  122. #define RESUME return(0)
  123. #define wart() static int NEAR wart()
  124. static int vstate = 0;
  125. static char vcmd = 0;
  126.  
  127. #define get 1
  128. #define rfile 2
  129. #define rdata 3
  130. #define ssinit 4
  131. #define ssfile 5
  132. #define ssdata 6
  133. #define sseof 7
  134. #define sseot 8
  135. #define ipkt 9
  136. #define rgen 10
  137.  
  138. #define BEGIN state =
  139.  
  140. int state = 0;
  141.  
  142. wart()
  143. {
  144.     int c,actno;
  145.     extern int tbl[];
  146.     while (1) {
  147.     c = input();
  148.     if ((actno = tbl[c + state*128]) != -1)
  149.         switch(actno) {
  150. case 1:
  151.     {                    /* send */
  152.     tinit(lclhWnd, krmState);
  153.     if (sinit())
  154.     BEGIN ssinit;
  155.     else {
  156.     Kermit.sstate = KRM_NO_SEND_FILE;
  157.     RESUME;
  158.     }
  159. }
  160.     break;
  161. case 2:
  162.     {                    /* receive */
  163.     tinit(lclhWnd, krmState);
  164.     BEGIN get;
  165. }
  166.     break;
  167. case 3:
  168.     {                    /* get */
  169.     tinit(lclhWnd, krmState);
  170.     vstate = get;
  171.     vcmd = 0;
  172.     sipkt('I');
  173.     BEGIN ipkt;
  174. }
  175.     break;
  176. case 4:
  177.     {                    /* host */
  178.     tinit(lclhWnd, krmState);
  179.     vstate = rgen;
  180.     vcmd = 'C';
  181.     sipkt('I');
  182.     BEGIN ipkt;
  183. }
  184.     break;
  185. case 5:
  186.     {                    /* generic */
  187.     tinit(lclhWnd, krmState);
  188.     vstate = rgen;
  189.     vcmd = 'G';
  190.     sipkt('I');
  191.     BEGIN ipkt;
  192. }
  193.     break;
  194. case 6:
  195.     {                /* got send_init */
  196.     rinit();
  197.   /* note : set block check type */
  198.     resetc();
  199.     BEGIN rfile;
  200. }
  201.     break;
  202. case 7:
  203.     {                /* got ack for I-packet */
  204.     spar(rcvpkt.data, rcvpkt.len);
  205.     if (vcmd) {
  206.     scmd(vcmd);
  207.     vcmd = 0;
  208.     }
  209.     if (vstate == get)
  210.     srinit();
  211.     BEGIN vstate;
  212. }
  213.     break;
  214. case 8:
  215.     {            /* got E for I-packet, ignore */
  216.     if (vcmd)
  217.     scmd(vcmd);
  218.     vcmd = 0;
  219.     if (vstate == get)
  220.     srinit();
  221.     BEGIN vstate;
  222. }
  223.     break;
  224. case 9:
  225.     {            /* got reply in ACK data */
  226.     bufemp(rcvpkt.data, rcvpkt.len, 2);
  227.     Kermit.sstate = KRM_COMPLETE;
  228.     RESUME;
  229. }
  230.     break;
  231. case 10:
  232.     {            /* got file header */
  233.     if (rcvfil()) {
  234.         ack(strlen(Kermit.filename), Kermit.filename);
  235.     BEGIN rdata;
  236.     }
  237.     else {
  238.     Kermit.sstate = KRM_FILE_OPEN_ERROR;
  239.     errpkt(lclhWnd, Kermit.sstate);
  240.     RESUME;
  241.     }
  242. }
  243.     break;
  244. case 11:
  245.     {
  246.     if (opent(lclhWnd)) {
  247.         ack(0,"");
  248.         BEGIN rdata;
  249.     }
  250.     else {
  251.     Kermit.sstate = KRM_TERM_OPEN_ERROR;
  252.     errpkt(lclhWnd, Kermit.sstate);
  253.     RESUME;
  254.     }
  255. }
  256.     break;
  257. case 12:
  258.     {                 /* got eot */
  259.     ack(0,"");
  260.     reot();
  261.     Kermit.sstate = KRM_COMPLETE;
  262.     RESUME;
  263. }
  264.     break;
  265. case 13:
  266.     {                /* got data */
  267.     if (Kermit.fileabort)
  268.     ack(1, "X");
  269.     else if (Kermit.batchabort)
  270.     ack(1, "Z");
  271.     else
  272.     ack(0,"");
  273.     if (bufemp(rcvpkt.data, rcvpkt.len, Kermit.displayfile) < 0) {
  274.     Kermit.sstate = KRM_FILE_WRITE_ERROR;
  275.     errpkt(lclhWnd, Kermit.sstate);
  276.     RESUME;
  277.     }
  278. }
  279.     break;
  280. case 14:
  281.     {                /* got end of file */
  282.     if (reof() < 0) {
  283.     Kermit.sstate = KRM_FILE_CLOSE_ERROR;
  284.     errpkt(lclhWnd, Kermit.sstate);
  285.     RESUME;
  286.     } else {
  287.         ack(0,"");
  288.     BEGIN rfile;
  289.     }
  290. }
  291.     break;
  292. case 15:
  293.     {                /* got ack to send init */
  294.     spar(rcvpkt.data, rcvpkt.len);
  295.   /* note : set block check type */
  296.     if (sfile()) {
  297.     resetc();
  298.     BEGIN ssfile;
  299.     } else {
  300.     Kermit.sstate = KRM_FILE_OPEN_ERROR;
  301.     errpkt(lclhWnd, Kermit.sstate);
  302.     RESUME;
  303.     }
  304. }
  305.     break;
  306. case 16:
  307.     {                 /* got ack to F */
  308.     if (sdata() <= 0) {
  309.     clsif();
  310.     seof("");
  311.     BEGIN sseof;
  312.     }
  313.     else
  314.     BEGIN ssdata;
  315. }
  316.     break;
  317. case 17:
  318.     { 
  319.     if (canned(rcvpkt.data)) {
  320.     clsif();
  321.     seof("D");
  322.     BEGIN sseof;
  323.     }
  324.     else if (sdata() <= 0) {
  325.     clsif();
  326.     seof("");
  327.     BEGIN sseof;
  328.     }
  329. }
  330.     break;
  331. case 18:
  332.     {                 /* got ack to EOF */
  333.     if (gnfile() > 0) {
  334.     if (sfile())
  335.         BEGIN ssdata;
  336.     else {
  337.          Kermit.sstate = KRM_FILE_OPEN_ERROR;
  338.         errpkt(lclhWnd, Kermit.sstate);
  339.         RESUME;
  340.     }
  341.     } else {                /* no next file */
  342.     seot();
  343.     BEGIN sseot;
  344.     }
  345. }
  346.     break;
  347. case 19:
  348.     {                 /* got ack to EOT */
  349.     Kermit.sstate = KRM_COMPLETE;
  350.     RESUME;
  351. }
  352.     break;
  353. case 20:
  354.     {                    /* partial packet */
  355.     if (Kermit.numtry >= Kermit.maxtry)
  356.     Kermit.sstate = KRM_RETRY_LIMIT;
  357.     RESUME;
  358. }
  359.     break;
  360. case 21:
  361.     {                     /* error packet */
  362.     bufemp(rcvpkt.data, rcvpkt.len, 2);
  363.     clsif();                /* close input files */
  364.     clsof(TRUE);            /* discard any output files */
  365.     Kermit.sstate = KRM_ERROR_PKT;
  366.     RESUME; 
  367. }
  368.     break;
  369. case 22:
  370.     {                    /* user abort */
  371.     Kermit.sstate = KRM_USERCNX;
  372.     errpkt(lclhWnd,Kermit.sstate);
  373.     RESUME;
  374. }
  375.     break;
  376. case 23:
  377.     { 
  378.     Kermit.sstate = KRM_UNKNOWN_PACKET;
  379.     errpkt(lclhWnd, Kermit.sstate);
  380.       RESUME;
  381. }
  382.     break;
  383.  
  384.         }
  385.     }
  386. }
  387.  
  388. int tbl[] = {
  389. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  390. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  391. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  392. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  393. 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  394. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  395. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  396. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  397. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  398. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  399. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  400. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  401. 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  402. 23, 23, 23,  6, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  403. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  404. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  405. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  406. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  407. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  408. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  409. 23, 23, 12, 23, 23, 21, 10, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  410. 23, 23, 23, 23, 23, 23, 23, 23, 11, 23, 23, 23, 23, 23, 23, 23, 
  411. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  412. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  413. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  414. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  415. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  416. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  417. 23, 23, 23, 23, 13, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  418. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 14, 23, 23, 23, 23, 23, 
  419. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  420. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  421. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  422. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  423. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  424. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  425. 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  426. 23, 23, 23, 23, 23, 23, 23, 23, 23, 15, 23, 23, 23, 23, 23, 23, 
  427. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  428. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  429. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  430. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  431. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  432. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  433. 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  434. 23, 23, 23, 23, 23, 23, 23, 23, 23, 16, 23, 23, 23, 23, 23, 23, 
  435. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  436. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  437. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  438. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  439. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  440. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  441. 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  442. 23, 23, 23, 23, 23, 23, 23, 23, 23, 17, 23, 23, 23, 23, 23, 23, 
  443. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  444. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  445. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  446. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  447. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  448. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  449. 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  450. 23, 23, 23, 23, 23, 23, 23, 23, 23, 18, 23, 23, 23, 23, 23, 23, 
  451. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  452. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  453. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  454. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  455. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  456. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  457. 23, 23, 23, 23, 23, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  458. 23, 23, 23, 23, 23, 23, 23, 23, 23, 19, 23, 23, 23, 23, 23, 23, 
  459. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  460. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  461. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  462. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  463. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  464. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  465. 23, 23, 23, 23, 23,  8, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  466. 23, 23, 23, 23, 23, 23, 23, 23, 23,  7, 23, 23, 23, 23, 23, 23, 
  467. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  468. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  469.  0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  470. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  471. 23, 23, 23, 23, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  472. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  473. 23, 23, 23, 23, 23, 21, 10, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  474. 23, 23, 23,  6, 23, 23, 23, 23, 11,  9, 23, 23, 23, 23, 23, 23, 
  475. 23, 23, 23,  4, 23, 23, 23,  5, 23, 23, 23, 23, 23, 23, 23, 23, 
  476. 20, 23,  3,  1, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  477. };
  478.  
  479.  
  480. /* following are all support routines */
  481. static void NEAR errpkt(HWND hWnd, int id)
  482. {
  483.  
  484.     char szError[80];
  485.     HANDLE hInstance = (HANDLE)GetWindowWord(hWnd, GWW_HINSTANCE);
  486.     int *len, datalen;
  487.  
  488.     *len = LoadString(hInstance, id, (LPSTR)szError, sizeof(szError));
  489.     datalen = encodebuf(sndpkt.data,szError,len);
  490.     spack('E', Kermit.pktnum, datalen, sndpkt.data);
  491.     clsif(); clsof(1);
  492. }
  493.  
  494. static void NEAR sipkt(char c)
  495. {
  496.  
  497.     BYTE buf[KRM_MAXPACKETSIZE];
  498.  
  499.     FlushComm(cid,1);
  500.     lclcount = 0;
  501.     spack(c,Kermit.pktnum,rpar(buf),buf);
  502.  
  503. }
  504.  
  505. static int NEAR sinit()
  506. {
  507.  
  508.     if ((Kermit.pNextFile = strtok(Kermit.pfilelist," ,")) != NULL) {
  509.         sipkt('S');
  510.         return(TRUE);
  511.     }
  512.     return(FALSE);
  513. }
  514.  
  515. static int NEAR sfile()
  516. {
  517.  
  518.     int *len;
  519.     register int datalen;
  520.     BYTE buf[20];
  521.  
  522.     Kermit.hInFile = GetSendFileName(Kermit.pNextFile);
  523.     if (Kermit.hInFile == -1)
  524.     return(0);
  525.  
  526.     strcpy(buf, Kermit.filename);
  527.     *len = strlen(Kermit.filename);
  528.     datalen = encodebuf(sndpkt.data, buf, len);
  529.  
  530.     nxtpkt();
  531.     spack('F',Kermit.pktnum, datalen, sndpkt.data);
  532.     return(1);
  533. }
  534.  
  535. static int NEAR sdata()
  536. {
  537.     register int len;
  538.  
  539.     if (rcvpkt.len) {
  540.         bufemp(rcvpkt.data, rcvpkt.len, 2);
  541.         SetDlgItemText(hWndXfer, IDD_SAVENAME,(LPSTR)rcvpkt.data);
  542.     }
  543.  
  544.     if (Kermit.fileabort || Kermit.batchabort)
  545.     return(-1);
  546.  
  547.     if ((len = bufill(sndpkt.data)) > 0) {
  548.         nxtpkt();
  549.         spack('D', Kermit.pktnum, len, sndpkt.data);
  550.     }
  551.     if (len < 0)
  552.     ShowTransactionError(lclhWnd, KRM_FILE_READ_ERROR);
  553.     return(len);
  554. }
  555.  
  556. static void NEAR seof(char *s)
  557. {
  558.  
  559.     nxtpkt();
  560.     if ((s != NULL) && (*s != NUL))
  561.     spack('Z', Kermit.pktnum, 1, s);
  562.     else
  563.     spack('Z', Kermit.pktnum, 0, "");
  564.  
  565. }
  566.  
  567. static void NEAR ack(int len, BYTE *s)
  568. {
  569.     spack('Y', Kermit.pktnum, len, s); 
  570.     nxtpkt();
  571. }
  572.  
  573. static int NEAR nxtpkt()
  574. {
  575.     Kermit.pktcount += 1;
  576.     return(Kermit.pktnum = (Kermit.pktnum + 1) & 63);
  577. }
  578.  
  579. void clsif() {
  580.     if (Kermit.hInFile) {
  581.         Kermit.hInFile = (HANDLE)close(Kermit.hInFile);
  582.     Kermit.hInFile = NULL;
  583.     }
  584.     Kermit.fileabort = FALSE;
  585. }
  586.  
  587. static int NEAR canned(char *buf)
  588. {
  589.     if (*buf == 'X')
  590.     Kermit.fileabort = TRUE;
  591.     if (*buf == 'Z')
  592.     Kermit.batchabort = TRUE;
  593.     return((Kermit.fileabort || Kermit.batchabort) ? 1 : 0);
  594. }
  595.  
  596. static int NEAR gnfile()
  597. {
  598.  
  599. /* don't do this if displaying on terminal */
  600.  
  601.     if (Kermit.batchabort || (Kermit.pNextFile = strtok(NULL, " ,")) == NULL)
  602.     return(0);
  603.  
  604.     return(1);
  605.    
  606. }
  607.  
  608. static void NEAR seot() {
  609.  
  610.     nxtpkt();
  611.     spack('B', Kermit.pktnum,0, "");
  612.     Kermit.fileabort = Kermit.batchabort = FALSE;
  613. }
  614.  
  615. static void NEAR rinit() {
  616.  
  617.     BYTE buf[100];
  618.  
  619.     spar(rcvpkt.data, rcvpkt.len);
  620.     ack(rpar(buf), buf);
  621. }
  622.  
  623. static int NEAR rcvfil() {
  624.     bufemp(rcvpkt.data, rcvpkt.len, 2);
  625.     if ((Kermit.hOutFile =
  626.         GetReceiveFileName(lclhWnd,rcvpkt.data)) == -1)
  627.     return(0);
  628.     return(1);
  629. }
  630.  
  631. static int NEAR reof() {
  632.  
  633.     register int x;
  634.  
  635.     if (Kermit.fileabort == FALSE)
  636.     Kermit.fileabort = rcvpkt.len ? (rcvpkt.data[0] == 'D') : FALSE;
  637.  
  638.     x = clsof(Kermit.fileabort | Kermit.batchabort);
  639.     
  640.     if (Kermit.fileabort || Kermit.batchabort)
  641.     Kermit.fileabort = FALSE;
  642.  
  643.     return(x);
  644. }
  645.  
  646. int clsof(int disp) {
  647.  
  648.     if (Kermit.displayfile)
  649.     return(1);
  650.  
  651.     if (Kermit.hOutFile) {
  652.         if ((Kermit.hOutFile = (HANDLE)close(Kermit.hOutFile)) != NULL)
  653.         return(-1);
  654.         if (disp && Kermit.filediscard)
  655.             unlink(myofstruct.szPathName);
  656.         return(1);
  657.     }
  658. }
  659.  
  660. static void NEAR reot() {
  661.  
  662.     Kermit.fileabort = Kermit.batchabort = FALSE;
  663.  
  664. }
  665.  
  666. static void NEAR resetc() {
  667.  
  668.     /* add appropriate code */
  669.  
  670. }
  671.  
  672. static void NEAR resend() {
  673.  
  674.     Kermit.numtry += 1;
  675.     Kermit.retrycount += 1;
  676.  
  677.     if (sndpkt.len)
  678.     ttoi(sndpkt.pktbuf, sndpkt.len);
  679.     else
  680.         spack('N', Kermit.pktnum, 0, "");
  681.  
  682.     if (IsWindow(hWndXfer))
  683.         UpdateXferBox();
  684. }
  685.  
  686. static void NEAR srinit() {
  687.  
  688.     int *len;
  689.    
  690.     *len = strlen(Kermit.pfilelist);
  691.     spack('R', Kermit.pktnum, 
  692.         encodebuf(sndpkt.data,Kermit.pfilelist,len), sndpkt.data);
  693. }
  694.  
  695. static void NEAR scmd(char cmd) {
  696.  
  697.     int *len;
  698.     register int datalen;
  699.  
  700.     switch (krmState) {
  701.     case IDM_KRM_FINISH:
  702.         datalen = 1;
  703.         sndpkt.data[0] = 'F';
  704.         break;
  705.     case IDM_KRM_BYE:
  706.     case IDM_KRM_LOGOUT:
  707.         datalen = 1;
  708.         sndpkt.data[0] = 'L';
  709.         break;
  710.        case IDM_KRM_REMOTEHOST:
  711.         *len = strlen(Kermit.pfilelist);
  712.         datalen = encodebuf(sndpkt.data, Kermit.pfilelist,len);
  713.         break;
  714.     default:
  715.             *len = strlen(Kermit.pRemoteCommand);
  716.         datalen = encodebuf(sndpkt.data, Kermit.pRemoteCommand,len);
  717.         break;
  718.     }
  719.     spack(cmd,Kermit.pktnum,datalen,sndpkt.data);
  720. }
  721.  
  722. static int NEAR opent(HWND hWnd) {
  723.  
  724.     BYTE crstring[3];
  725.  
  726.     if (krmInitMainDisplay(hWnd, Kermit.DispCharWidth, Kermit.DispCharHeight)) {
  727.         bufemp(rcvpkt.data, rcvpkt.len, 2);
  728.     krmMainStringDisplay(hWnd, rcvpkt.data, rcvpkt.len);
  729.     crstring[0] = CR;
  730.     crstring[1] = LF;
  731.         krmMainStringDisplay(hWnd, crstring,2);
  732.      Kermit.displayfile = 1;
  733.     return(TRUE);
  734.     }
  735.     return FALSE;                
  736. }
  737.  
  738. static BOOL NEAR paritycheck() {
  739.  
  740.     DCB commdata;
  741.  
  742.     GetCommState(cid, (DCB FAR *)&commdata);
  743.     if ((commdata.Parity == NOPARITY) && (commdata.ByteSize == 8))
  744.     return FALSE;
  745.     return TRUE;
  746. }
  747.  
  748. static int NEAR rpar(BYTE *data) {
  749.  
  750.     register int i = 0;
  751.  
  752.     data[i++] = (BYTE)tochar(local.maxpacketsize);
  753.     data[i++] = (BYTE)tochar(local.timeout);
  754.     data[i++] = (BYTE)tochar(local.padcount);
  755.     data[i++] = ctl(local.padchar);
  756.     data[i++] = (BYTE)tochar(local.eol);
  757.     data[i++] = local.quote;
  758.  
  759.     switch (Kermit.rqf) {
  760.     case -1 :
  761.     case  1 :
  762.         if (paritycheck())
  763.             Kermit.ebq = local.binquote = '&';
  764.         break;
  765.     case 0 :
  766.     case 2 :
  767.         break;
  768.     }        
  769.     data[i++] = local.binquote;
  770.  
  771. /* fixup: get these fields straight */
  772.  
  773.     data[i++] = (BYTE)(local.chksumtype + '0');
  774.     data[i++] = local.rptprefix;
  775.  
  776.     return(i);
  777. }
  778.  
  779. static void NEAR spar(BYTE *data, int len) {
  780.     
  781.     register int i = 0;
  782.     register int intval;
  783.     char charval;
  784.  
  785.     intval = (i < len) ? unchar(data[i++]) : KRM_DEFPACKETSIZE;
  786.     remote.maxpacketsize = (intval < KRM_MINPACKETSIZE)
  787.                          ? KRM_DEFPACKETSIZE : intval;
  788.  
  789.     intval = (i < len) ? unchar(data[i++]) : KRM_DEFTIMEOUT;
  790.     remote.timeout = ((intval < 0) || (intval > 65)) ? KRM_DEFTIMEOUT : intval;
  791.     Kermit.mstimeout = 1000 * remote.timeout;
  792.  
  793.     remote.padcount = KRM_DEFPADCOUNT;
  794.     remote.padchar = KRM_DEFPADCHAR;
  795.     if (i < len) {
  796.            remote.padcount = unchar(data[i++]);
  797.         if (i < len)
  798.         if ((((charval = ctl(data[i++])) >= 0) && (charval < SP))
  799.                  || (charval == DEL))
  800.             remote.padchar = charval;
  801.     }
  802.  
  803.     intval = (i < len) ? unchar(data[i++]) : KRM_DEFEOL;
  804.     remote.eol = ((intval > SOH) || (intval < SP)) ? intval : KRM_DEFEOL;
  805.  
  806.     charval = (i < len) ? data[i++] : KRM_DEFQUOTE;
  807.     remote.quote = ((charval > SP) && (charval < '?')) ||
  808.                ((charval > '_') && (charval < DEL)) ? 
  809.                 charval : KRM_DEFQUOTE;
  810.  
  811.     charval = remote.binquote = (i < len) ? data[i++] : 0;
  812.     if (charval == 'Y')
  813.     Kermit.rqf = 1;
  814.     else if ((charval > 32 && charval < '?') || 
  815.         (charval > '_' && charval < DEL))
  816.     Kermit.rqf = 2;
  817.     else
  818.     Kermit.rqf = 0;
  819.     switch (Kermit.rqf) {
  820.     case 0 :
  821.         Kermit.ebqflg = FALSE;
  822.         break;
  823.     case 1 :
  824.         if (paritycheck()) {
  825.         Kermit.ebqflg = TRUE;
  826.         Kermit.ebq = '&';
  827.         }
  828.         break;
  829.     case 2:
  830.         if (Kermit.ebqflg = (Kermit.ebq == local.binquote ||
  831.                     local.binquote == 'Y'))
  832.         Kermit.ebq = charval;
  833.             break;
  834.     }        
  835.  
  836. /* fixup the following code */
  837.  
  838.     intval = 1;
  839.     if (i < len) {
  840.         intval = data[i++] - '0';
  841.         if ((intval < 1) || (intval > 3))
  842.         intval = 1;
  843.     }
  844.     remote.chksumtype = intval;
  845.  
  846.     if (i < len) {
  847.     remote.rptprefix = charval = data[i++];
  848.      Kermit.rptflg = ((charval > 32 && charval < '?') || 
  849.                     (charval > '_' && charval < DEL));
  850.     }
  851.     else
  852.     Kermit.rptflg = FALSE;
  853.  
  854.     Kermit.maxsenddatalen = remote.maxpacketsize - 2 - Kermit.chksumtype;
  855.  
  856. }
  857.  
  858. static void NEAR spack(BYTE type, int num, int len, BYTE *data) {
  859.  
  860.     WORD chksum = 0;
  861.     register int i, k;
  862.  
  863.     sndpkt.len = 0;
  864.     sndpkt.data[len] = NUL;
  865.  
  866.     if (k = remote.padcount) {
  867.         memset(sndpkt.pktbuf, remote.padchar, k);
  868.     ttoi(sndpkt.pktbuf, k);
  869.     }
  870.  
  871.     k = 0;
  872.  
  873.     sndpkt.pktbuf[k++] = sndpkt.mark;
  874.     chksum += sndpkt.pktbuf[k++] = (BYTE)tochar(len + 3);
  875.     chksum += sndpkt.pktbuf[k++] = (BYTE)tochar(num);
  876.     chksum += sndpkt.pktbuf[k++] = type;
  877.  
  878.     for (i = 0; i < len; i++)
  879.         chksum += sndpkt.pktbuf[k++] = data[i];
  880.  
  881.     chksum = (((chksum & 0300) >> 6) + chksum) & 077;
  882.     sndpkt.pktbuf[k++] = (BYTE)tochar(chksum);
  883.  
  884.     sndpkt.pktbuf[k++] = (BYTE)remote.eol;
  885.     sndpkt.pktbuf[k] = NUL;
  886.     
  887.     ttoi(sndpkt.pktbuf,k);
  888.     sndpkt.len = k;
  889. }
  890.  
  891. static void NEAR ttoi(BYTE *buf, int len)
  892. {
  893.  
  894.     COMSTAT mycomstat;
  895.     register int inque;
  896.  
  897.     do {
  898.         GetCommError(cid, (COMSTAT FAR *)&mycomstat);
  899.       inque = mycomstat.cbOutQue;
  900.     } while(inque);
  901.  
  902.    WriteComm(cid, (LPSTR)buf, len);
  903.  
  904. }
  905.  
  906. static int NEAR bufill(BYTE buffer[]) {
  907.  
  908.     register int numloaded, numread;
  909.     BYTE buf[KRM_MAXPACKETSIZE];
  910.     int numrem;
  911.  
  912.     if ((numread = read(Kermit.hInFile,buf,Kermit.maxsenddatalen)) <= 0) {
  913.     numloaded = numread;
  914.     if (numread == 0)
  915.          Kermit.percentage = 100;
  916.     } else {
  917.         numrem = numread;
  918.         numloaded = encodebuf(buffer, buf, &numrem);
  919.         lseek(Kermit.hInFile, (LONG)(-numrem), SEEK_CUR);
  920.         if (Kermit.filesize) {
  921.             Kermit.bytesmoved += numread - numrem;
  922.         Kermit.percentage = (int)(Kermit.bytesmoved *100 / Kermit.filesize);
  923.         }
  924.     }
  925.     return(numloaded);
  926. }
  927.  
  928. static int NEAR encodebuf(BYTE outbuf[], BYTE inbuf[], int *inbufsize) {
  929.  
  930.     register int i,j;
  931.     BYTE t, t7;
  932.     int maxbufsize = Kermit.maxsenddatalen - 3;  /* char + prefix */
  933.     char quote = remote.quote;
  934.     char binquote = Kermit.ebq;
  935.  
  936.     if (Kermit.ebqflg) {
  937.         for (i = 0, j = 0 ; j < *inbufsize ; ) {
  938.         t = inbuf[j++];
  939.         if (t & 0x80)
  940.         outbuf[i++] = binquote;
  941.         if (((t7 = t & 0x7f) < SP) || (t7 == DEL)) {
  942.         outbuf[i++] = quote;
  943.         t7 = ctl(t7);
  944.         }
  945.         else if ((t7 == quote) || (t7 == binquote))
  946.         outbuf[i++] = quote;
  947.         outbuf[i++] = t7;
  948.         if (i > maxbufsize)
  949.             break;
  950.     }
  951.     }
  952.     else {
  953.         for (i = 0, j = 0 ; j < *inbufsize ; ) {
  954.         t = inbuf[j++];
  955.         if ((t7 = t & 0x7f) < SP || t7 == DEL || t7 == quote) {
  956.             outbuf[i++] = quote;
  957.             if (t7 != quote)
  958.             t = ctl(t);
  959.         }
  960.         outbuf[i++] = t;
  961.         if (i > maxbufsize)
  962.             break;
  963.         }
  964.     }
  965.     *inbufsize -= j;
  966.     return(i);
  967. }
  968.  
  969. static int NEAR bufemp(BYTE *buffer, int len, int dest) {
  970.  
  971.     register int i,j;
  972.     int result;
  973.     BYTE t, t7, wbuf[100];
  974.     BYTE bitset;
  975.     char quote = local.quote;
  976.     char binquote = Kermit.ebq;
  977.  
  978.     if (Kermit.ebqflg) {
  979.         for (i = 0, j = 0; i < len; i++) {
  980.         t = buffer[i];
  981.         if (t == binquote) {
  982.             t = buffer[++i];
  983.             bitset = 0x80;
  984.         }
  985.         else
  986.             bitset = 0;
  987.         if (t == quote) {
  988.             t = buffer[++i];
  989.             if (((t7 = t & 0x7f) != quote) && (t7 != binquote))
  990.             t = ctl(t);
  991.         }
  992.         wbuf[j++] = t | bitset;
  993.         }
  994.     }
  995.     else {
  996.         for (i = 0, j = 0; i < len; i++) {
  997.         t = buffer[i];
  998.         if (t == quote) {
  999.             t = buffer[++i];
  1000.             if ((t & 0x7f) != quote)
  1001.             t = ctl(t);
  1002.         }
  1003.         wbuf[j++] = t;
  1004.         }
  1005.     }
  1006.     wbuf[j] = NUL;
  1007.  
  1008.     switch (dest) {
  1009.     case 2 :
  1010.         strcpy(rcvpkt.data, wbuf);
  1011.         rcvpkt.len = j;
  1012.         return (TRUE);
  1013.         case 1 :
  1014.             krmMainStringDisplay(lclhWnd, wbuf, j);
  1015.         return (TRUE);
  1016.     default:
  1017.         if ((result = write(Kermit.hOutFile, wbuf, j)) >= 0)
  1018.         Kermit.bytesmoved += result;
  1019.             if ((result < j) || (result == -1))
  1020.         return(-1);
  1021.             else
  1022.         return(result);
  1023.     }
  1024. }
  1025.  
  1026. static HANDLE NEAR GetSendFileName(char *name) {
  1027.  
  1028.     HANDLE hfile;
  1029.     struct stat buf;
  1030.  
  1031.     hfile = OpenFile((LPSTR)name, (OFSTRUCT FAR *)&myofstruct,OF_READ);
  1032.  
  1033.     if (hfile != -1) {
  1034.     Kermit.filename = (strrchr(myofstruct.szPathName,'\\') + 1);
  1035.         SetDlgItemText(hWndXfer, IDD_FILENAME,(LPSTR)Kermit.filename);    
  1036.     fstat(hfile, &buf);
  1037.     Kermit.filesize = buf.st_size;
  1038.     }
  1039.     Kermit.bytesmoved = 0;
  1040.     Kermit.percentage = 0;
  1041.     return hfile;
  1042. }
  1043.  
  1044. static HANDLE NEAR GetReceiveFileName(HWND hWnd, BYTE *packet)
  1045. {
  1046.  
  1047.     HANDLE hInstance = (HANDLE)GetWindowWord(hWnd, GWW_HINSTANCE);
  1048.     register int i, j;
  1049.     char filename[13];
  1050.     char ext[5];
  1051.     int numresult;
  1052.     char *ptrresult;
  1053.     BOOL gotextension;
  1054.     HANDLE hfile;
  1055.     char tempname[9], genstring[20];
  1056.     int filecount;
  1057.  
  1058.     Kermit.newname_flag = FALSE;
  1059.  
  1060.     memset(filename, NUL, 13);
  1061.     ext[0] = NUL;
  1062.  
  1063.     SetDlgItemText(hWndXfer, IDD_FILENAME,(LPSTR)packet);    
  1064.  
  1065.     ptrresult = strtok(packet, ".");        /* look for any extension */
  1066.     numresult = strlen(ptrresult);        /* find out how long */
  1067.     numresult = numresult < 8 ? numresult : 8;
  1068.     strncpy(filename,ptrresult,numresult);    /* load up name */
  1069.  
  1070.     gotextension = FALSE;
  1071.     ptrresult = strtok(NULL, ".");        /* get extension */
  1072.     if (ptrresult != NULL) {
  1073.     strcpy(ext,".");
  1074.     strncat(ext, ptrresult,3);
  1075.     ext[4] = NUL;
  1076.     strcat(filename, ext);
  1077.     gotextension = TRUE;
  1078.     }
  1079.  
  1080.     if (Kermit.filewarning) {
  1081.     for (filecount = 0; filecount < INT_MAX; filecount++) {
  1082.             if ((hfile = OpenFile((LPSTR)filename,
  1083.                 (OFSTRUCT FAR *)&myofstruct,OF_EXIST)) == -1)
  1084.             break;
  1085.         ptrresult = strtok(filename, ".");
  1086.         strcpy(tempname, ptrresult);        
  1087.         numresult = strlen(ptrresult);        
  1088.         for (i = numresult; i < 8; i++)        
  1089.             tempname[i] = '0';
  1090.         numresult = strlen(itoa(filecount + 1, genstring,10));        
  1091.  
  1092.         for (i = 8 - numresult, j = 0; i < 8; i++,j++)
  1093.             tempname[i] = genstring[j];        
  1094.         tempname[8] = NUL;
  1095.         strcpy(filename, tempname);
  1096.         if (gotextension)
  1097.             strcat(filename,ext);
  1098.     }
  1099.     if (filecount > 0)
  1100.         Kermit.newname_flag = TRUE;
  1101.     }
  1102.  
  1103.     hfile = OpenFile((LPSTR)filename,(OFSTRUCT FAR *)&myofstruct,OF_CREATE);
  1104.     if (hfile != -1) {
  1105.         Kermit.filename = (strrchr(myofstruct.szPathName,'\\') + 1);
  1106.         SetDlgItemText(hWndXfer, IDD_SAVENAME,(LPSTR)Kermit.filename);
  1107.     }
  1108.     Kermit.bytesmoved = 0;
  1109.     return (hfile);
  1110. }
  1111.  
  1112. static int NEAR input() {
  1113.  
  1114.     int type, rsn, seq;
  1115.     int startcount;
  1116.  
  1117.     if (Kermit.sstate > 0) {
  1118.     type = Kermit.sstate;
  1119.     Kermit.sstate = 0;
  1120.     return(type);
  1121.     }
  1122.  
  1123.     if (Kermit.protocolabort)
  1124.     return('$');
  1125.  
  1126. again:
  1127.     if (!Kermit.inpacket) {
  1128.         if (IsWindow(hWndXfer))
  1129.             UpdateXferBox();
  1130.      if (Kermit.timer)
  1131.         SetTimer(lclhWnd, KRM_WAITPACKET, Kermit.mstimeout, Kermit.fpTimer);
  1132.     Kermit.inpacket = TRUE;
  1133.     }
  1134.     startcount = lclcount;
  1135.     lclcount = getpacket(lclbuf, lclcount);
  1136.     lclbuf += startcount - lclcount;
  1137.     if (rcvpkt.state == PS_DONE) {
  1138.     rcvpkt.state = PS_SYNCH;
  1139.     Kermit.inpacket = FALSE;
  1140.     if (Kermit.timer) {
  1141.         KillTimer(lclhWnd, KRM_WAITPACKET);
  1142.         Kermit.timeout = FALSE;
  1143.     }
  1144.     type = rcvpkt.type;
  1145.     rsn = rcvpkt.num;
  1146.     seq = Kermit.pktnum;
  1147.     if (type == sndpkt.pktbuf[3])
  1148.         goto again;
  1149.     if ((rsn != seq) || (type == 'N') || (type == 'Q')) {
  1150.         if ((type == 'N') && (rsn == (seq + 1) & 63)) {
  1151.         Kermit.numtry = 0;
  1152.         return ('Y');
  1153.         }
  1154.         else {
  1155.         resend();
  1156.         goto again;
  1157.         }
  1158.     }
  1159.     Kermit.numtry = 0;
  1160.     return (type);
  1161.     }
  1162.     else {
  1163.     if (Kermit.timeout) {
  1164.         Kermit.timeout = FALSE;
  1165.         resend();
  1166.     }
  1167.     return('p');
  1168.     }
  1169. }
  1170.  
  1171. /* get a packet, complete or partial */
  1172. static int NEAR getpacket(BYTE *str, int len) {
  1173.  
  1174.     register BYTE t;
  1175.     register int i;
  1176.  
  1177.     while (len) {
  1178.     switch (rcvpkt.state) {
  1179.         case PS_SYNCH:
  1180.             while (len) {
  1181.             if (*str != rcvpkt.mark) {
  1182.                 str++;
  1183.                 len--;
  1184.             }
  1185.                 else
  1186.                 break;
  1187.             }
  1188.         if (len) {
  1189.             str++; 
  1190.             len--;
  1191.             rcvpkt.state = PS_LEN;
  1192.             rcvpkt.cchksum = 0;
  1193.             rcvpkt.data_count = 0;
  1194.             rcvpkt.data[0] = NUL;
  1195.         }
  1196.         break;
  1197.  
  1198.         case PS_LEN:
  1199.         if ((t = *str) == rcvpkt.mark)
  1200.             rcvpkt.state = PS_SYNCH;
  1201.             else {
  1202.             rcvpkt.state = PS_NUM;
  1203.             rcvpkt.len = unchar(t) - 2 - Kermit.chksumtype;
  1204.             rcvpkt.cchksum += t;
  1205.             str++;
  1206.             len--;
  1207.         }
  1208.         break;
  1209.  
  1210.         case PS_NUM:
  1211.         if ((t = *str) == rcvpkt.mark)
  1212.             rcvpkt.state = PS_SYNCH;
  1213.             else {
  1214.             rcvpkt.state = PS_TYPE;
  1215.             rcvpkt.num = unchar(t);
  1216.             rcvpkt.cchksum += t;
  1217.             str++;
  1218.             len--;
  1219.         }
  1220.         break;
  1221.  
  1222.         case PS_TYPE:
  1223.         if ((t = *str) == rcvpkt.mark)
  1224.             rcvpkt.state = PS_SYNCH;
  1225.             else {
  1226.             if (rcvpkt.len)
  1227.                 rcvpkt.state = PS_DATA;
  1228.             else
  1229.             rcvpkt.state = PS_CHK;
  1230.             rcvpkt.type = t;
  1231.             rcvpkt.cchksum += t;
  1232.             str++;
  1233.             len--;
  1234.         }
  1235.         break;
  1236.  
  1237.         case PS_DATA:
  1238.         for (i = rcvpkt.data_count; i < rcvpkt.len; i++) {
  1239.             if ((t = *str) == rcvpkt.mark)
  1240.             break;
  1241.             else {
  1242.             rcvpkt.data[i] = t;
  1243.             rcvpkt.cchksum += t;
  1244.             rcvpkt.data_count += 1;
  1245.             str++;
  1246.             len--;
  1247.             if (len <= 0)
  1248.                 break;
  1249.             }
  1250.         }
  1251.         if (t == rcvpkt.mark)
  1252.             rcvpkt.state = PS_SYNCH;
  1253.         else if (rcvpkt.data_count == rcvpkt.len) {
  1254.             rcvpkt.data[rcvpkt.len] = NUL;
  1255.             rcvpkt.state = PS_CHK;
  1256.         }
  1257.         break;
  1258.  
  1259.         case PS_CHK:
  1260.         if ((t = *str) == rcvpkt.mark)
  1261.             rcvpkt.state = PS_SYNCH;
  1262.             else {
  1263.             rcvpkt.rchksum = unchar(t);
  1264.             str++;
  1265.             len--;
  1266.             rcvpkt.cchksum = (((rcvpkt.cchksum & 0xC0) >> 6)
  1267.                     + rcvpkt.cchksum) & 0x3f;
  1268.             if (rcvpkt.cchksum != rcvpkt.rchksum)
  1269.             rcvpkt.type = 'Q';
  1270.             rcvpkt.state = PS_DONE;
  1271.         }
  1272.         break;
  1273.         case PS_DONE:
  1274.         if ((t = *str) == (BYTE)local.eol) {
  1275.             str++;
  1276.             len--;
  1277.         }
  1278.         return len;
  1279.     } /* switch */
  1280.     } /* while */
  1281.     return len;
  1282. }
  1283.  
  1284. static void NEAR ShowTransactionError(HWND hWnd, int id)
  1285. {
  1286.  
  1287.     char szMessage[80];
  1288.     char szCaption[40];
  1289.     HANDLE hInstance = (HANDLE)GetWindowWord(hWnd, GWW_HINSTANCE);
  1290.  
  1291.     LoadString(hInstance, IDS_KRM_KERMIT, (LPSTR)szCaption, sizeof(szCaption));
  1292.     LoadString(hInstance, id, (LPSTR)szMessage, sizeof(szMessage));
  1293.  
  1294.     if (Kermit.bell)
  1295.     MessageBeep(MB_OK | MB_ICONASTERISK);
  1296.  
  1297.     MessageBox(hWnd,(LPSTR)szMessage,(LPSTR)szCaption, MB_OK | MB_ICONASTERISK);
  1298. }
  1299.  
  1300. static void NEAR UpdateXferBox()
  1301. {
  1302.  
  1303.     char str[20];
  1304.     static int prevcount;
  1305.  
  1306.     if (IsIconic(lclhWnd))
  1307.     InvalidateRect(lclhWnd, (LPRECT)NULL, FALSE);
  1308.     else {
  1309.         SetDlgItemText(hWndXfer,IDD_BYTESMOVED,ltoa(Kermit.bytesmoved,str,10));
  1310.         SetDlgItemInt(hWndXfer,IDD_PACKETS,Kermit.pktcount,0);
  1311.         if (krmState == IDM_KRM_SEND)
  1312.             SetDlgItemInt(hWndXfer,IDD_PERCENTAGE,Kermit.percentage,0);
  1313.     if (prevcount != Kermit.retrycount) {
  1314.             SetDlgItemInt(hWndXfer,IDD_RETRIES,Kermit.retrycount,0);
  1315.         prevcount = Kermit.retrycount;
  1316.      }
  1317.     }
  1318. }
  1319.